簡單來說,就是當用戶沒有網路連線時,背景同步就會將數據發送到server。
這裡有一點非常重要,在service worker上,是無法暫存POST Request(我之前實作的Request都是GET所以是OK的)。我們可以暫存Post Request回傳的Response,但就是無法暫存POST Request本身以便我們之後再發送。現在有一種我們可以使用的技術,就是「使用service worker來註冊synchronous task」。
「註冊synchronous task」基本上是在告訴service worker,把我們想要發送的數據視為同步工作。另外我們還需要儲存伴隨著POST Request發送的data(可能是json data、圖片或是其它種數據類型),我這裡將它儲存在browser的indexedDB中。
現在,我們已準備好在網路連線重新建立之後來發送它。如果我們在原本沒有網路連線下重新建立連線,service worker將透過監聽同步事件(sync event)將synchronous task發送出去。一旦觸發這個event,service worker就會將Request數據發送到server。
在註冊Synchronous Task前,要先能獲取用戶提交的表單資料,首先在feed.js中取得下列selector的資料,並且監聽submit event,當用戶提交時就進行相對應的處理:
var form = document.querySelector('form');
var titleInput = document.querySelector('#title');
var locationInput = document.querySelector('#location');
form.addEventListener('submit', function(event) {
event.preventDefault(); // 預設會直接將資料submit出去,這裡我不需要所以先取消
// 簡單的防呆機制
if(titleInput.value.trim() === '' || locationInput.value.trim() === '') {
alert('請輸入貼文資訊!!');
return;
};
// 最後要記得跳出發文頁面
closeCreatePostModal();
});
接下來就可以開始註冊同步工作了,我直接在上面的closeCreatePostModal()後面接續寫下去:
if('serviceWorker' in navigator && 'SyncManager' in window) {
navigator.serviceWorker.ready.then(function(sw) {
sw.sync.register('sync-new-post');
});
}
說明一下這裡的code,我先確認用戶的browser有無支援service worker(因為沒有的話就無法執行背景同步惹),以及有無支援SyncManager API。如果都有的話,當service worker確定已經install和activate,就可以開始註冊同步工作了。
register() method可以接非常多的參數,這裡我只輸入id這個參數。我給目前要同步的task一個名為「sync-new-post」的id值,之後當網路恢復連線時,service worker就可以根據這個id找到待處理的task是哪些。
這裡我必須要說一下,以目前瀏覽器對「背景同步的」的支援程度實在是非常非常低。所以目前我的PWA就算實作出這個功能,只能在android平台上表現出來,而在ios平台就完全沒有辦法惹QQ
Day19 結束!!